import sys
import asyncio
from threading import Thread
from PyQt5.QtCore import QThread, pyqtSignal
from MyTT import EMA
import numpy as np
import pandas as pd
from tqsdk import TqApi
from db_manager import connect_db, get_monitored_products
import time 
from tqsdk import TqApi, TqAuth, TqAccount, TqSim,TqKq

class AsyncOpenCloseStrategy():
    def __init__(self, symbols, lots):
        # 调用父类的初始化方法
        super().__init__()
        #快期模拟账户
        tq_kq = TqKq()
        self.api = TqApi(account=tq_kq, auth=TqAuth("cps168", "alibaba999"))
        self.symbols = symbols
        self.lots = lots
        self.running = False
        self.active_symbols = set()  # 新增运行状态跟踪
        self.running = True
        self._run_all_symbols()

    # def run(self):
    #     print("************************已启动策略************************")
    #     self.running = True
    #     self._run_all_symbols()


    def _run_all_symbols(self):
        """并行处理所有品种"""
        print(f"开始处理品种列表: {self.symbols}")
        #用线程方式处理每个待监控的交易品种
        for symbol in self.symbols:
            Thread(target=self._process_product, args=(symbol,)).start()


    def _process_product(self, symbol):
        """单个品种处理协程"""
        self.active_symbols.add(symbol)
        #print(f"{time.strftime('%X')} 策略开始运行。。。")  # 修正时间格式
        try:  
            while True:
                #print(f"{time.strftime('%X')} {symbol} 正在运行...")  # 修正时间格式
                quote = self.api.get_quote(symbol)  # 移出async with块        
                klines = self.api.get_kline_serial(symbol, 5*60, 500)        
                #等待行情更新
                # deadline = time.time() + 1 # 设置10秒的超时时间
                # self.api.wait_update(deadline=deadline)
                time.sleep(2)
                if not self.running:  # 添加停止检查
                    return
                #print(f"{time.strftime('%X')} {symbol} 行情已更新。。。！")
                if self.api.is_changing(klines, "close"):
                    print(f"{time.strftime('%X')} K线数据已变化,{symbol} 价格是：{quote.last_price}")
                    q = (3*klines.close + klines.low + klines.open + klines.high) / 6
                    ma_values = self._calculate_ma(q)
                    short_ma = ma_values['ma']
                    ema_7 = ma_values['ema']
                    
                    position = self.api.get_position(symbol)
                    
                    # 平空仓逻辑
                    if short_ma[-2] > ema_7[-2]:  
                        if position.pos_short > 0:
                            self.api.insert_order(symbol, direction="BUY", offset="CLOSE", 
                                            volume=position.pos_short)
                    # 开多仓逻辑
                    if position.pos_long == 0 and position.pos_short == 0 and short_ma[-3] < ema_7[-3] and short_ma[-2] > ema_7[-2]:
                        self.api.insert_order(symbol, direction="BUY", offset="OPEN", 
                                        volume=self.lots)
                        
                    # 平多仓逻辑
                    if short_ma[-2] < ema_7[-2]:  
                        if position.pos_long > 0:
                            self.api.insert_order(symbol, direction="SELL", offset="CLOSE", 
                                            volume=position.pos_long)
                    # 开空仓逻辑
                    if position.pos_long == 0 and position.pos_short == 0 and short_ma[-3] > ema_7[-3] and short_ma[-2] < ema_7[-2]:
                        self.api.insert_order(symbol, direction="SELL", offset="OPEN", 
                                        volume=self.lots)
                #print("************************策略运行结束************************")
        except Exception as e:
            print(f"Error processing symbol {symbol}: {e}")                        
        finally:
            self.active_symbols.remove(symbol)

    # def _calculate_ma(self, q):
    #     """自定义权重计算（与原版完全一致）"""
    #     weights = np.arange(26, 0, -1)
    #     ma = []
    #     q_array = np.array(q)
    #     for i in range(len(q_array)):
    #         if i < 26:
    #             ma.append(np.nan)
    #             continue
    #         window = q_array[i-26:i+1]
    #         ma.append(np.dot(window, weights) / 351)
        
    #     ema_7 = EMA(pd.Series(ma), 7)
    #     return {'ma': ma, 'ema': ema_7.tolist()}

    def _calculate_ma(self, q):
        """自定义权重计算（与原版完全一致）"""
        weights = np.arange(26, 0, -1)
        ma = []
        q_array = np.array(q)
        for i in range(len(q_array)):
            if i < 25:  # 修改为25，因为窗口大小现在是26
                ma.append(np.nan)
                continue
            window = q_array[i-25:i+1]  # 修改为i-25，这样窗口大小就是26
            ma.append(np.dot(window, weights) / 351)
        
        ema_7 = EMA(pd.Series(ma), 7)
        return {'ma': ma, 'ema': ema_7.tolist()}

    async def stop(self):
        """停止策略"""
        self.running = False
        if self.main_task:
            await self.main_task
            self.main_task = None